<template>
  <view class="container">
    <!-- 顶部标题 -->
    <text class="title-bar">智能图像识别</text>

    <!-- 上传区（没有照片时显示） -->
    <view v-if="!hasPhoto" class="upload-section">
      <icon type="camera" size="80" color="#aaa" class="upload-icon" />
      <text class="upload-text">上传或拍摄照片</text>
      <text class="desc">支持自动识别照片内容</text>
    </view>

    <!-- 已上传照片（有照片时显示，覆盖上传区域） -->
    <view v-else>
      <!-- 识别中弹窗 -->
      <view v-if="dialogVisible" class="dialog-mask">
        <view class="dialog-box">
          <text class="dialog-title">AI预测中</text>
          <progress :percent="percentage" show-info stroke-width="10" active/>
          <text class="dialog-footer">请耐心等待约3秒钟</text>
        </view>
      </view>

      <!-- 图片区 -->
      <view class="photo-preview">
        <view class="image-card">
          <image :src="url_1 || photos[0]" class="result-photo" mode="aspectFit" @tap="previewImage(url_1 || photos[0])" />
          <view class="img-desc">原始图像</view>
        </view>
        <view class="image-card">
          <image :src="url_2" class="result-photo" mode="aspectFit" @tap="previewImage(url_2)" />
          <view class="img-desc">
            检测结果
            <button v-if="url_2" class="download-btn" @tap="downloadImage(url_2)" type="primary">下载</button>
          </view>
        </view>
      </view>

      <!-- 检测结果表格 -->
      <view v-if="featureList.length" class="result-table-card">
        <view class="table-title">检测目标</view>
        <scroll-view scroll-y style="max-height: 300px;">
          <view class="result-table">
            <view class="table-row table-header">
              <view class="table-cell">目标类别</view>
              <view class="table-cell">目标大小</view>
              <view class="table-cell">置信度</view>
            </view>
            <view v-for="(item, idx) in featureList" :key="idx" class="table-row">
              <view class="table-cell">{{ item[2] }}</view>
              <view class="table-cell">{{ item[0] }}</view>
              <view class="table-cell">{{ item[1] }}</view>
            </view>
          </view>
        </scroll-view>
      </view>
    </view>

    <!-- 按钮区 -->
    <view class="button-group">
      <template v-if="!hasPhoto">
        <button class="btn blue" @tap="chooseFromAlbum">从相册选择</button>
        <button class="btn confirm" @tap="takePhoto">拍摄照片</button>
      </template>
      <template v-else>
        <button class="btn gray" @tap="resetPhotos">重新选择</button>
        <button class="btn green" @tap="confirmPhoto" :disabled="loading">确认识别</button>
      </template>
    </view>

   <!-- 识别案例标题栏 -->
<!-- 错误提示 -->
<view v-if="waitReturn && !dialogVisible && !loading && !featureList.length" class="error-tip">{{ waitReturn }}</view>

<view class="example-title-bar">
  <icon type="success_no_circle" size="30" color="#3acfff" />
  <text class="example-title-text">识别案例</text>
</view>

<!-- 案例图片展示，一行一个 -->
<view class="case-demo-wrap">
  <view class="case-demo-item" v-for="(item, idx) in caseDemoList" :key="idx">
    <image :src="item.img" class="case-demo-img" mode="aspectFill" @tap="previewImage(item.img)" />
    <text class="case-demo-desc">{{ item.desc }}</text>
  </view>
</view>

  </view>
</template>

<script setup>
import { ref, computed } from 'vue'

const photos = ref([])
const url_1 = ref('')
const url_2 = ref('')
const featureList = ref([])
const dialogVisible = ref(false)
const percentage = ref(0)
const loading = ref(false)
const waitReturn = ref('')

// 识别案例图片数据
const caseDemoList = [
  { img: '/static/03.jpeg', desc: '动物检测' },
  { img: '/static/04.jpeg', desc: '书本检测' },
  { img: '/static/05.jpeg', desc: '水果识别' }
]

const hasPhoto = computed(() => photos.value.length > 0)

// 图片预览
const previewImage = (url) => {
  if (!url) return
  wx.previewImage({
    current: url,
    urls: [url]
  })
}

// 图片下载（仅支持线上图片）
const downloadImage = (url) => {
  if (!url) return
  wx.downloadFile({
    url: url,
    success: function(res) {
      if (res.statusCode === 200) {
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success: function() {
            wx.showToast({ title: '保存成功', icon: 'success' })
          },
          fail: function() {
            wx.showToast({ title: '保存失败', icon: 'none' })
          }
        })
      } else {
        wx.showToast({ title: '下载失败', icon: 'none' })
      }
    },
    fail: function() {
      wx.showToast({ title: '下载失败', icon: 'none' })
    }
  })
}

const chooseFromAlbum = () => {
  wx.chooseImage({
    count: 1,
    sizeType: ['compressed'],
    sourceType: ['album'],
    success: res => {
      photos.value = res.tempFilePaths
      url_1.value = ''
      url_2.value = ''
      featureList.value = []
      waitReturn.value = ''
    }
  })
}

const takePhoto = () => {
  wx.chooseImage({
    count: 1,
    sizeType: ['compressed'],
    sourceType: ['camera'],
    success: res => {
      photos.value = res.tempFilePaths
      url_1.value = ''
      url_2.value = ''
      featureList.value = []
      waitReturn.value = ''
    }
  })
}

const resetPhotos = () => {
  photos.value = []
  url_1.value = ''
  url_2.value = ''
  featureList.value = []
  waitReturn.value = ''
}

const confirmPhoto = () => {
  if (!photos.value.length) return
  dialogVisible.value = true
  percentage.value = 0
  loading.value = true
  waitReturn.value = ''
  featureList.value = []

  let timer = setInterval(() => {
    if (percentage.value < 99) {
      percentage.value += 33
    } else {
      percentage.value = 99
    }
  }, 30)

  wx.uploadFile({
    url: 'http://192.168.31.193:5003/upload',
    filePath: photos.value[0],
    name: 'file',
    formData: {},
    success: res => {
      percentage.value = 100
      clearInterval(timer)
      dialogVisible.value = false
      loading.value = false
      try {
        const data = JSON.parse(res.data)
        url_1.value = data.image_url
        url_2.value = data.draw_url
        const keys = Object.keys(data.image_info)
        const list = []
        for (let i = 0; i < keys.length; i++) {
          data.image_info[keys[i]][2] = keys[i]
          list.push(data.image_info[keys[i]])
        }
        featureList.value = list
        wx.showToast({ title: '识别成功', icon: 'success', duration: 1500 })
      } catch (err) {
        waitReturn.value = '识别结果解析失败'
      }
    },
    fail: err => {
      clearInterval(timer)
      dialogVisible.value = false
      loading.value = false
      waitReturn.value = '上传或识别失败，请重试'
    }
  })
}
</script>

<style scoped>
.container {
  background: #f7faff;
  min-height: 100vh;
  padding: 30rpx;
}

.title-bar {
  text-align: center;
  font-size: 34rpx;
  font-weight: bold;
  color: #27c3cc;
  margin-bottom: 20rpx;
}

.upload-section {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: linear-gradient(to bottom, #e0f4ff, #f2faff);
  border-radius: 20rpx;
  padding: 100rpx 40rpx;
  margin-top: 40rpx;
  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
}

.upload-icon {
  width: 100rpx;
  height: 100rpx;
  margin-bottom: 20rpx;
}

.upload-text {
  font-size: 34rpx;
  font-weight: bold;
  color: #444;
}

.desc {
  color: #999;
  font-size: 24rpx;
  margin-top: 10rpx;
}

.photo-preview {
  display: flex;
  justify-content: space-between;
  margin-top: 30rpx;
  width: 100%;
  gap: 20rpx;
}

.image-card {
  flex: 1;
  background: linear-gradient(to bottom, #d9f4ff, #c7f0f6);
  border-radius: 16rpx;
  padding: 20rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  box-shadow: 0 2px 12rpx rgba(0, 0, 0, 0.08);
}

.result-photo {
  width: 90%;
  height: 240rpx;
  border-radius: 10rpx;
  background: #f5f5f5;
}

.img-desc {
  color: #21b3b9;
  font-size: 26rpx;
  margin-top: 12rpx;
  font-weight: bold;
}

.result-table-card {
  background: #ffffff;
  border-radius: 16rpx;
  padding: 20rpx;
  margin-top: 40rpx;
  box-shadow: 0 2px 10rpx rgba(0, 0, 0, 0.04);
}

.table-title {
  font-size: 32rpx;
  font-weight: bold;
  color: #21b3b9;
  text-align: center;
  margin-bottom: 16rpx;
}

.result-table {
  width: 100%;
}
.table-row {
  display: flex;
  justify-content: space-between;
  padding: 12rpx 0;
  border-bottom: 1px solid #f0f0f0;
  font-size: 26rpx;
}
.table-header {
  background: #e6f3ff;
  font-weight: bold;
}
.table-cell {
  flex: 1;
  text-align: center;
  color: #444;
}

.error-tip {
  color: #e74c3c;
  text-align: center;
  margin: 30rpx 0;
  font-size: 28rpx;
}

.button-group {
  margin-top: 50rpx;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 20rpx;
  justify-content: center;
}

.btn {
  width: 320rpx;
  height: 90rpx;
  line-height: 90rpx;
  font-size: 30rpx;
  border-radius: 16rpx;
  text-align: center;
  color: #fff;
  font-weight: bold;
  border: none;
}
.green {
  background: linear-gradient(to right, #79e09e, #52d68b);
}
.blue {
  background: linear-gradient(to right, #8ed8f8, #3acfff);
}
.gray {
  background: #cccccc;
}
.confirm {
  background: linear-gradient(to right, #ffd699, #fcae66);
}

.dialog-mask {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}
.dialog-box {
  background: #fff;
  border-radius: 20rpx;
  padding: 50rpx;
  width: 600rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.dialog-title {
  font-size: 34rpx;
  color: #3a9cff;
  font-weight: bold;
  margin-bottom: 30rpx;
}
.dialog-footer {
  font-size: 26rpx;
  color: #999;
  margin-top: 20rpx;
}

.example-card-group {
  width: 100%;
  display: flex;
  justify-content: space-between;
  margin-top: 60rpx;
}
.example-card {
  width: 48%;
  background: #fff;
  border-radius: 20rpx;
  padding: 30rpx 20rpx;
  display: flex;
  align-items: center;
  gap: 20rpx;
  box-shadow: 0 2px 8rpx rgba(0, 0, 0, 0.06);
}
.blue-card {
  background: #e6f3ff;
}
.card-text {
  font-size: 28rpx;
  color: #444;
}

/* 案例图片横滑样式 */
.example-title-bar {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 16rpx;
  padding: 40rpx 0 20rpx;
}

.example-title-text {
  font-size: 30rpx;
  font-weight: bold;
  color: #3acfff;
}

/* 优化后的识别案例展示样式：一行一个卡片 */
.case-demo-wrap {
  display: flex;
  flex-direction: column;
  gap: 30rpx;
  margin-top: 10rpx;
}

.case-demo-item {
  width: 100%;
  background: #ffffff;
  border-radius: 24rpx;
  box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.06);
  overflow: hidden;
  transition: transform 0.3s;
}

.case-demo-item:hover {
  transform: scale(1.02);
}

.case-demo-img {
  width: 100%;
  height: 300rpx;
  object-fit: cover;
  display: block;
}

.case-demo-desc {
  padding: 24rpx;
  font-size: 28rpx;
  font-weight: 600;
  color: #444;
  text-align: center;
  background: #f6fcff;
}

.download-btn {
  margin-top: 12rpx;
  padding: 12rpx 24rpx;
  font-size: 26rpx;
  color: #fff;
  background: linear-gradient(135deg, #4fc3f7, #0288d1);
  border-radius: 32rpx;
  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  border: none;
  text-align: center;
  line-height: 1.5;
}

.download-btn::after {
  border: none; /* 去掉默认点击态边框 */
}

.download-btn:hover {
  transform: scale(1.03);
  background: linear-gradient(135deg, #03a9f4, #0277bd);
}


</style>
